/* api */
import { batchEditProductType, getRelationModifyProductList } from '@src/api/ProductV2Api'
/* enum */
import StorageModuleEnum from '@model/enum/StorageModuleEnum'
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
import DateFormatEnum from '@model/enum/DateFormatEnum'
import { ProductFieldNameMappingEnum, ProductTypeFieldNameMappingEnum } from '@model/enum/FieldMappingEnum'
/* hooks */
// import { useQualityInfoComputedRuleAutoComputedWithStartTime } from '@hooks/useQualityInfo'
/* model */
import Page from '@model/Page.ts'
import { RelationModifyProductListResult, RelationModifyProductListItem, RelationModifyProductListItemField } from '@model/param/out/Product'
import { 
  ProductTypeRelationProductListTableListColumns,
  ProductTypeRelationProductFieldMappingEnum,
  QualityInfoFieldNameToDisplayNameMap,
  QualityInfoTypeDisplayNameMap
} from '@src/component/business/BizProductTypeRelationModifyDialog/BizProductTypeRelationModifyDialogModel'
import { RelationModifyProductListParams } from '@model/param/in/ProductCatalog'
import { MODIFY } from '@src/model/const/Alert'
import { BatchEditProductCatalogModel } from '@model/param/in/Product'
/* scss */
import '@src/component/business/BizProductTypeRelationModifyDialog/BizProductTypeRelationModifyDialog.scss'
/* service */
import { getFieldName } from '@service/FieldService'
/* vue */
import VC from '@model/VC'
import { t } from '@src/locales'
import { Component, Emit, Prop } from 'vue-property-decorator'
import { CreateElement, VNode } from 'vue'
import { QualityRuleForm } from '@model/entity/QualityRule'
import { computed, ComputedRef, ref } from 'vue'
/* util */
import Log from '@src/util/log.ts'
import Platform from '@src/util/platform'
import { storageSet } from '@src/util/storage.ts'
import { randomString, uuid } from 'pub-bbx-utils'
import { isArray, isEmpty } from '@src/util/type'
import { openTabForProductView } from '@src/util/business/openTab'
/* types */
import Column from '@model/types/Column'
import { formatFormField } from '@src/filter/form'
import { defaultTableData } from '@src/util/table'

interface SpanData {
  rowspan: number
  colspan: number
}

interface SpanMethodCallBackParams {
  // 当前行
  row: RelationModifyProductListItem
  // 当前列
  column: Column
  // 当前行号
  rowIndex: number 
  // 当前列号
  columnIndex: number
}

enum BizProductTypeRelationModifyDialogEventEnum {
  NotModify = 'notModify',
  Success = 'success'
}

// 表格列默认宽度
const TableColumnDefaultWidth = '120px'

@Component({
  name: ComponentNameEnum.BizProductTypeRelationModifyDialog
})
class BizProductTypeRelationModifyDialog extends VC {
  
  @Prop({ default: '' }) readonly name: string | undefined
  @Prop({ default: () => [] }) readonly ids: number[] | undefined
  @Prop({ default: () => ({}) }) readonly qualityRuleForm: QualityRuleForm | undefined
  
  /* 表格列 */
  private columns: Column[] = ProductTypeRelationProductListTableListColumns
  /* 等待状态 */
  private pending: boolean = false
  /* 产品管理信息表格页数据 */
  private relationProductPage: Page<RelationModifyProductListItem[]> = new Page()
  /* 查询产品类型修改关联的产品列表参数 */
  private relationModifyProductListBaseParams: RelationModifyProductListParams = {
    cateLogId: [],
    changeList: []
  }
  private relationModifyProductListParams: RelationModifyProductListParams = this.relationModifyProductListBaseParams
  /* 行合并数据 */
  private spanMethodData: number[] = []
  private spanPositionNumber: number = 0
  /* 是否显示弹窗 */
  private showDialog: boolean = false
  /* 表格key 随机数 */
  private tableKey: string = randomString()
  
  /* 产品类型名称 */
  get productTypeName(): string {
    return this.name || ''
  }
  
  get qualityRuleFormRef(): ComputedRef<QualityRuleForm> {
    const emptyQualityRuleForm = {
      [ProductTypeFieldNameMappingEnum.QualityStartTime]: '',
      [ProductTypeFieldNameMappingEnum.QualityTime]: {
        qualityTimeNumber: '',
        qualityTimeType: ''
      },
      [ProductTypeFieldNameMappingEnum.QualityFiledName]: ''
    }
    
    return computed(() => this.qualityRuleForm || emptyQualityRuleForm)
  }
  
  @Emit(BizProductTypeRelationModifyDialogEventEnum.NotModify)
  private emitNotModifyEventHandler() {}
  
  @Emit(BizProductTypeRelationModifyDialogEventEnum.Success)
  private emitModifySuccessEventHandler(result: Record<string, any>) {
    return result
  }
  
  private buildParams(): RelationModifyProductListParams {
    return {
      ...this.relationModifyProductListBaseParams,
      pageSize: this.relationProductPage.pageSize,
      pageNum: this.relationProductPage.pageNum,
    }
  }
  
  private buildBatchEditParams(): BatchEditProductCatalogModel {
    let num: any = [];
    let time: any = [];

    // 产品类型ids集合
    const ids: number[] = isEmpty(this.ids) ? this.relationModifyProductListBaseParams?.cateLogId || [] : this.ids as number[]
    // 质保时长
    const qualityTimeNumber: string | number | undefined = this.qualityRuleForm?.qualityTime?.qualityTimeNumber
    // 质保起算时间
    const qualityStartTime: string | number | undefined = this.qualityRuleForm?.qualityStartTime

    if (qualityTimeNumber) {
      num = [{
        fieldName: 'qualityDuration',
        fieldValue: Number(qualityTimeNumber),
        otherValue: this.qualityRuleForm?.qualityTime?.qualityTimeType || '',
      }]
    }

    if (qualityStartTime) {
      time = [{
        fieldName: 'qualityStartDate',
        fieldValue: qualityStartTime
      }]
    }
    
    return {
      changeList: [...num, ...time],
      ids,
      flag: true
    }
  }
  // 获取关联的产品
  private fetchRelationModifyProductList() {
    this.pending = true
    
    this.relationModifyProductListParams = this.buildParams()
    getRelationModifyProductList(this.relationModifyProductListParams)
      .then((data: RelationModifyProductListResult) => {
        const isSuccess = data?.success
        if (!isSuccess) {
          return Platform.alert(data?.message)
        }
        
        const result = data?.result || {}

        this.relationProductPage.merge(result)
        this.setRelationProductPageList()
        this.setSpanMethodData(this.relationProductPage.list)
      })
      .finally(() => {
        this.pending = false
      })
  }
  
  /**
   * @description 获取属性
  */
  private getAttributes() {
    return {
      props: {
        width: '765px',
        title: t('common.base.toast'),
        show: this.showDialog
      },
      on: {
        'update:show': (val: boolean) => {
          this.showDialog = val
        }
      },
      directives: [
        {
          name: 'loading',
          value: this.pending
        }
      ]
    }
  }
  
  private getDisplayName(row: Record<string, any>): string {
    return QualityInfoFieldNameToDisplayNameMap[row?.changeField || ''] || ''
  }
  
  /**
   * @description: 获取字段值
   * @param {string} fieldName 字段名称
   * @param {any} row 表格行数据
   * @return {String | null}
  */  
  private getValue(column: Column, row: Record<string, any>): string | null {
    if(!column) return ''
    const value: string = row?.[column.field || ''] || ''
    return QualityInfoTypeDisplayNameMap[value] ? QualityInfoTypeDisplayNameMap[value] : formatFormField(column, row)
  }
  
  private getSpanMethodData(spanMethodCallBackParams: SpanMethodCallBackParams): SpanData | void {
    const { row, column, rowIndex, columnIndex } = spanMethodCallBackParams
    
    // 非第一列 (非产品名称列) 则返回
    if (columnIndex !== 0) return
    
    return {
      rowspan: this.spanMethodData[rowIndex],
      colspan: 1
    }
  }
  
  private hide(): void {
    this.showDialog = false
  }
  
  /** 
   * @description 表格拖动事件
  */
  private headerDragendHandler(newWidth: number, oldWidth: number, tableColumn: any = {}) {
    Log.succ(Log.Start, this.headerDragendHandler.name)
    
    let field: string = tableColumn.property || ''
    
    this.columns.forEach(column => {
      if (column.field === field) {
        column.width = newWidth
      }
    })
    
    const columns = this.simplifyTableColumnsProperty(this.columns)
    this.saveDataToStorage(StorageKeyEnum.TaskAllotTableColumns, columns)
  }
  
  private initialize() {
    this.relationProductPage.list = []
  }
  
  /**
   * @description: 不修改产品信息
   * @return {void}
   */
  private notModifyProductData(): void {
    this.hide()
    this.emitNotModifyEventHandler()
  }
  
  /**
   * @description: 分页当前页码数据变化事件
   * @param {number} pageNum 页码数
   * @return {void}
   */  
  private onPaginationPageNumChangedHandler(pageNum: number): void {
    this.relationProductPage.pageNum = pageNum
    
    this.search()
  }
  
  /**
   * @description: 分页当前页大小数据变化事件
   * @param {number} pageSize 页大小
   * @return {void}
   */  
  private onPaginationPageSizeChangedHandler(pageSize: number): void {    
    this.relationProductPage.pageSize = pageSize
    this.relationProductPage.pageNum = 1
    
    this.search()
  }
  
  /** 
   * @description 打开弹窗
   * -- 支持外部调用的
  */
  public outsideShow(relationModifyProductListBaseParams: RelationModifyProductListParams) {
    this.relationModifyProductListBaseParams = relationModifyProductListBaseParams
    this.show()
  }
  
  /** 
   * @description 打开弹窗
  */
  private show() {
    this.showDialog = true
    this.relationProductPage = new Page()
    this.initialize()
    this.fetchRelationModifyProductList()
  }
  
  private setSpanMethodData(list: RelationModifyProductListItem[]) {
    let spanMethodData: number[] = []
    
    // 处理数据列表，生成一个与行数相同的数组记录每一行设置的合并数
    list.forEach((item: RelationModifyProductListItem, index: number) => {
      if (index == 0) {
        spanMethodData.push(1)
        this.spanPositionNumber = index
        return false
      }
      
      if (item.flag && item.flag == list[index - 1]?.flag) {
        spanMethodData[this.spanPositionNumber] += 1
        spanMethodData.push(0)
      } else {
        spanMethodData.push(1)
        this.spanPositionNumber = index
      }
      
    })
    
    this.spanMethodData = spanMethodData
  }
  
  private setRelationProductPageList() {
    let list: RelationModifyProductListItem[] = []
    
    this.relationProductPage.list.forEach((item: RelationModifyProductListItem, index: number) => {
      if (!isArray(item.productChangeVO) || isEmpty(item.productChangeVO)) {
        list.push(item)
        return
      }
      
      item.productChangeVO.forEach((field: RelationModifyProductListItemField) => {
        list.push({
          ...item,
          ...field,
          flag: `${index}_${item.id}`
        })
      })
      
    })
    
    this.relationProductPage.list = list.filter(item => {
      return item.changeField === ProductFieldNameMappingEnum.QualityEndTime || ProductFieldNameMappingEnum.QualityStartTime
    })
  }
  
  private search() {
    this.initialize()
    this.fetchRelationModifyProductList()
  }
  
  /* 精简列属性 */
  private simplifyTableColumnsProperty(columns: Column[]): Column[] {
    return (
      columns.map((column: Column) => ({
        field: column.field,
        show: column.show,
        width: column.width
      }))
    )
  }
  
  /**
   * @description 保存数据到缓存
  */
  private saveDataToStorage(key: string, data: any) {
    storageSet(key, data, StorageModuleEnum.Task)
  }
  
  /**
   * @description: 同步修改产品信息
   * @return {void}
   */
  private syncModifyProductData(): void {
    this.pending = true
    const params = this.buildBatchEditParams()
    
    batchEditProductType(params)
      .then(response => {
        const isSuccess = response.success
        if (!isSuccess) return
        
        this.hide()
        this.emitModifySuccessEventHandler(response)
      })
      .catch(error => {
        Log.error(error, this.syncModifyProductData.name)
      })
      .finally(() => {
        this.pending = false
      })
  }
  
  private renderRelationTitle() {
    return (
      <div class='biz-product-type-relation-modify-dialog-title'>
        <i18n path="common.base.tip.confirmModifyProductType">
          <span palce="count" class='biz-product-type-relation-modify-dialog-title-number'>{ this.relationProductPage.total }</span>
          {this.productTypeName && (
            <span place="name">：{ this.productTypeName }</span>
          )}
        </i18n>
      </div>
    )
  }
  
  /** 
   * @description 渲染表格列
  */
  private renderTableColumnField(scope: any, column: Column) {
    // 字段名称
    const fieldName = getFieldName(column)
    // 行数据
    const row: RelationModifyProductListItem = scope.row
    // 值
    let value = column.field ? scope.row[column.field] : ''
    
    // 产品名称
    if (fieldName === ProductTypeRelationProductFieldMappingEnum.Name) return this.renderColumnWithName(column, row)
    // 修改字段
    if (fieldName === ProductTypeRelationProductFieldMappingEnum.DisplayName) return this.renderColumnWithDisplayName(column, row)
    // 修改前的值
    if (fieldName === ProductTypeRelationProductFieldMappingEnum.ModifyBeforeValue) return this.renderColumnWithModifyBeforeValue(column, row)
    // 修改后的值
    if (fieldName === ProductTypeRelationProductFieldMappingEnum.ModifyAfterValue) return this.renderColumnWithModifyAfterValue(column, row)
    
    return null
  }
  
  /* 渲染产品名称 */
  private renderColumnWithName(column: Column, row: RelationModifyProductListItem) {
    return (
      <div>
        <div 
          class='view-detail-btn task-list-numbering'
          onClick={() => openTabForProductView(row.id || '')}
        >
          { this.getValue(column, row) }
        </div>
      </div>
    )
  }
  
  /* 渲染修改字段名称 */
  private renderColumnWithDisplayName(column: Column, row: RelationModifyProductListItem) {
    return (
      <div>
        { this.getDisplayName(row) }
      </div>
    )
  }
  
  /* 渲染修改前的值 */
  private renderColumnWithModifyBeforeValue(column: Column, row: RelationModifyProductListItem) {
    return (
      <div>
        { this.getValue(column, row) }
      </div>
    )
  }
  
  /* 渲染修改后的值 */
  private renderColumnWithModifyAfterValue(column: Column, row: RelationModifyProductListItem) {
    return (
      <div>
        { this.getValue(column, row) }
      </div>
    )
  }
  
  private renderRelationProductTable() {
    return (
      <div class='relation-product-table'>
        <el-table
            border
            data={this.relationProductPage.list}
            header-row-class-name='base-table-header-v3'
            key={this.tableKey}
            row-class-name='base-table-row-v3'
            ref='TaskAllotUserElTableComponent'
            rowKey={uuid()}
            spanMethod={(spanMethodCallBackParams: SpanMethodCallBackParams) => this.getSpanMethodData(spanMethodCallBackParams)}
            stripe
            onHeader-dragend={(newWidth: number, oldWidth: number, column: any) => this.headerDragendHandler(newWidth, oldWidth, column)}
          >
            {
              this.columns && this.columns.filter((column: Column) => column.show).map((column: Column) => {
                return (
                  <el-table-column
                    fixed={column.fixed}
                    label={column.label}
                    key={column.field}
                    minWidth={column.width ? `${column.width}px` : TableColumnDefaultWidth}
                    prop={column.field}
                    resizable={true}
                    sortable={column.sortable}
                    showOverFlowTooltip={true}
                  >
                    { (scope: any) => this.renderTableColumnField(scope, column) }
                  </el-table-column>
                )
              })
              
            }
          </el-table>
      </div>
    )
  }
  
  /**
   * @description: 渲染分页条
   * @param {Number} total 总条数
   * @return {VNode}
   */  
  public renderPaginationBar(): VNode {
    return (
      <div class='relation-product-table-pagination'>
        <el-pagination
          background
          hide-on-single-page
          pageSizes={defaultTableData.defaultPageSizes}
          onCurrent-change={(pageNum: number) => this.onPaginationPageNumChangedHandler(pageNum)}
          onSize-change={(pageSize: number) => this.onPaginationPageSizeChangedHandler(pageSize)}
          pageSize={this.relationProductPage.pageSize}
          currentPage={this.relationProductPage.pageNum}
          layout='prev, pager, next, sizes'
          total={this.relationProductPage.total}
        >
        </el-pagination>
      </div>
    )
  }
  
  render(h: CreateElement) {
    const attrs = this.getAttributes()
    
    return (
      <div class={ComponentNameEnum.BizProductTypeRelationModifyDialog}>
        <base-modal {...attrs}>
          
          { this.renderRelationTitle() }
          { this.renderRelationProductTable() }
          { this.renderPaginationBar() }
          
          <div slot='footer' class='dialog-footer'>
            <el-button onClick={() => this.syncModifyProductData()}>
              {t('common.base.syncModify')}
            </el-button>
            <el-button
              type='primary' 
              onClick={() => this.notModifyProductData()}
              disabled={this.pending}
            >
              {t('common.base.notModify')}
            </el-button>
          </div>
        
        </base-modal>
      </div>
    )
  }
}

export default BizProductTypeRelationModifyDialog
